﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ModeloMagiPack.Entidades;
using DALMagiPack.Funcionalidad;

namespace BLLMagiPack.Managers
{
    public class BLLFactura
    {
        public void CargarFactura(Factura factura, List<FacturaDetalle> detalles, List<FacturaCheque> facturaCheques, int idOrden, Proveedor proveedor)
        {
            DALMagiPack<Factura> dalFactura = new DALMagiPack<Factura>();
            dalFactura.IniciarConexión();
            dalFactura.IniciarTransacción();

            DALMagiPack<FacturaDetalle> dalDetalle = new DALMagiPack<FacturaDetalle>() { Connection = dalFactura.Connection, Transaction = dalFactura.Transaction };
            DALMagiPack<FacturaCheque> dalFacturaCheque = new DALMagiPack<FacturaCheque> { Connection = dalFactura.Connection, Transaction = dalFactura.Transaction };

            dalFactura.Insertar(factura);

            foreach (FacturaDetalle detalle in detalles)
            {
                detalle.IdFactura = factura.IdFactura;
                dalDetalle.Insertar(detalle);
            }

            foreach (FacturaCheque asignacion in facturaCheques)
            {
                asignacion.IdFactura = factura.IdFactura;
                dalFacturaCheque.Insertar(asignacion);
            }

            if (proveedor == null)
            {
                DALMagiPack<OrdenFactura> dalOrdenFactura = new DALMagiPack<OrdenFactura>() { Connection = dalFactura.Connection, Transaction = dalFactura.Transaction };
                OrdenFactura ordenFactura = new OrdenFactura();
                ordenFactura.IdOrden = idOrden;
                ordenFactura.IdFactura = factura.IdFactura;

                dalOrdenFactura.Insertar(ordenFactura);
            }
            else
            {
                DALMagiPack<OrdenFacturaProveedor> dalOrdenFacturaProveedor = new DALMagiPack<OrdenFacturaProveedor>() { Connection = dalFactura.Connection, Transaction = dalFactura.Transaction };
                OrdenFacturaProveedor ordenFacturaProveedor = new OrdenFacturaProveedor();
                ordenFacturaProveedor.IdOrden = idOrden;
                ordenFacturaProveedor.IdProveedor = proveedor.IdProveedor;
                ordenFacturaProveedor.IdFactura = factura.IdFactura;

                dalOrdenFacturaProveedor.Insertar(ordenFacturaProveedor);
            }

            dalFactura.ConfirmarTransacción();
            dalFactura.CerrarConexión();
        }
        public void CargarFactura(Factura factura, List<FacturaDetalle> detalles, List<FacturaCheque> facturaCheques, int idOrden)
        {
            CargarFactura(factura, detalles, facturaCheques, idOrden, null);
        }

        public void ModificarFactura(Factura factura, List<FacturaDetalle> detalles, List<FacturaCheque> facturaCheques, Proveedor proveedor)
        {
            DALMagiPack<Factura> dalFactura = new DALMagiPack<Factura>();
            dalFactura.IniciarConexión();
            dalFactura.IniciarTransacción();

            dalFactura.Modificar(factura);

            DALMagiPack<FacturaDetalle> dalDetalle = new DALMagiPack<FacturaDetalle>() { Connection = dalFactura.Connection, Transaction = dalFactura.Transaction };
            foreach (FacturaDetalle item in dalDetalle.Traer(new FacturaDetalle() { IdFactura = factura.IdFactura }, new List<Filtro>() { new Filtro() { Columna = NombresColumnas.IdFactura, Tipo = TipoFiltro.Equal } }))
                dalDetalle.Eliminar(item);

            foreach (FacturaDetalle detalle in detalles)
            {
                detalle.IdFactura = factura.IdFactura;
                dalDetalle.Insertar(detalle);
            }

            DALMagiPack<FacturaCheque> dalFacturaCheque = new DALMagiPack<FacturaCheque> { Connection = dalFactura.Connection, Transaction = dalFactura.Transaction };
            foreach (FacturaCheque item in dalFacturaCheque.Traer(new FacturaCheque() { IdFactura = factura.IdFactura }, new List<Filtro>() { new Filtro() { Columna = NombresColumnas.IdFactura, Tipo = TipoFiltro.Equal } }))
                dalFacturaCheque.Eliminar(item);

            foreach (FacturaCheque asignacion in facturaCheques)
            {
                asignacion.IdFactura = factura.IdFactura;
                dalFacturaCheque.Insertar(asignacion);
            }

            if (proveedor != null)
            {
                DALMagiPack<OrdenFacturaProveedor> dalOrdenFacturaProveedor = new DALMagiPack<OrdenFacturaProveedor>() { Connection = dalFactura.Connection, Transaction = dalFactura.Transaction };
                OrdenFacturaProveedor ordenFacturaRoveedor = dalOrdenFacturaProveedor.Traer(new OrdenFacturaProveedor() { IdFactura = factura.IdFactura }, new List<Filtro>() { new Filtro() { Columna = NombresColumnas.IdFactura, Tipo = TipoFiltro.Equal } }).FirstOrDefault();
                ordenFacturaRoveedor.IdProveedor = proveedor.IdProveedor;
                dalOrdenFacturaProveedor.Modificar(ordenFacturaRoveedor);
            }

            dalFactura.ConfirmarTransacción();
            dalFactura.CerrarConexión();
        }
        public void ModificarFactura(Factura factura, List<FacturaDetalle> detalles, List<FacturaCheque> facturaCheques)
        {
            ModificarFactura(factura, detalles, facturaCheques, null);
        }

        public Dictionary<int, Factura> TraerFacturasProveedores(int idOrden)
        {
            DALMagiPack<OrdenFacturaProveedor> dalOrdenFacturaProveedor = new DALMagiPack<OrdenFacturaProveedor>();
            List<OrdenFacturaProveedor> asignaciones = dalOrdenFacturaProveedor.Traer(new OrdenFacturaProveedor() { IdOrden = idOrden },
                                                                                    new List<Filtro>() { new Filtro(){ Columna = NombresColumnas.IdOrden, Tipo = TipoFiltro.Equal} 
                                                                                    });

            List<Factura> facturas = new List<Factura>();
            foreach (OrdenFacturaProveedor item in asignaciones)
                facturas.Add(TraerFactura(item.IdFactura));

            facturas = facturas.OrderByDescending(f => f.FechaVencimiento).ToList();

            Dictionary<int, Factura> resultado = new Dictionary<int, Factura>();

            foreach (Factura item in facturas)
            {
                int idProveedor = asignaciones.Where(a => a.IdFactura == item.IdFactura).Select(a => a.IdProveedor).FirstOrDefault();
                resultado.Add(idProveedor, item);
            }

            return resultado;
        }

        public List<Factura> TraerFacturasCliente(int idOrden)
        {
            DALMagiPack<OrdenFactura> dalOrdenFactura = new DALMagiPack<OrdenFactura>();
            List<Factura> facturas = new List<Factura>();

            foreach (OrdenFactura item in dalOrdenFactura.Traer(new OrdenFactura() { IdOrden = idOrden }, new List<Filtro>() { new Filtro() { Columna = NombresColumnas.IdOrden, Tipo = TipoFiltro.Equal } }))
                facturas.Add(new BLLFactura().TraerFactura(item.IdFactura));

            return facturas;
        }

        public Factura TraerFactura(int idFactura)
        {
            DALMagiPack<Factura> dalFactura = new DALMagiPack<Factura>();
            return dalFactura.Traer(new Factura() { IdFactura = idFactura }, new List<Filtro>() { new Filtro(){ Columna = NombresColumnas.IdFactura, Tipo = TipoFiltro.Equal} }).FirstOrDefault();
        }

        public decimal CalcularTotal(int idFactura)
        {
            Factura factura = TraerFactura(idFactura);
            List<FacturaDetalle> detalles = new BLLFacturaDetalle().TraerDetalles(idFactura);

            if (detalles.Count == 0)
                return 0;
            else
            {
                decimal subtotal = (detalles.Sum(d => d.Cantidad) * detalles.Sum(d => d.PrecioUnitario));
                decimal concha = ((decimal)factura.IVA / 100 + 1);
                decimal total = subtotal * concha;
                return total;
            }
        }

        public void EliminarFactura(int idFactura)
        {
            DALMagiPack<Factura> dalFactura = new DALMagiPack<Factura>();
            dalFactura.IniciarConexión();
            dalFactura.IniciarTransacción();

            DALMagiPack<FacturaDetalle> dalDetalle = new DALMagiPack<FacturaDetalle>() { Connection = dalFactura.Connection, Transaction = dalFactura.Transaction };
            foreach (FacturaDetalle item in dalDetalle.Traer(new FacturaDetalle() { IdFactura = idFactura }, new List<Filtro>() { new Filtro() { Columna = NombresColumnas.IdFactura, Tipo = TipoFiltro.Equal } }))
                dalDetalle.Eliminar(item);

            DALMagiPack<FacturaCheque> dalFacturaCheque = new DALMagiPack<FacturaCheque> { Connection = dalFactura.Connection, Transaction = dalFactura.Transaction };
            foreach (FacturaCheque item in dalFacturaCheque.Traer(new FacturaCheque() { IdFactura = idFactura }, new List<Filtro>() { new Filtro() { Columna = NombresColumnas.IdFactura, Tipo = TipoFiltro.Equal } }))
                dalFacturaCheque.Eliminar(item);

            DALMagiPack<OrdenFacturaProveedor> dalOrdenFacturaProveedor = new DALMagiPack<OrdenFacturaProveedor>() { Connection = dalFactura.Connection, Transaction = dalFactura.Transaction };
            OrdenFacturaProveedor ordenFacturaRoveedor = dalOrdenFacturaProveedor.Traer(new OrdenFacturaProveedor() { IdFactura = idFactura }, new List<Filtro>() { new Filtro() { Columna = NombresColumnas.IdFactura, Tipo = TipoFiltro.Equal } }).FirstOrDefault();
            if (ordenFacturaRoveedor != null)
                dalOrdenFacturaProveedor.Eliminar(ordenFacturaRoveedor);

            DALMagiPack<OrdenFactura> dalOrdenFactura = new DALMagiPack<OrdenFactura>() { Connection = dalFactura.Connection, Transaction = dalFactura.Transaction };
            OrdenFactura ordenFactura = dalOrdenFactura.Traer(new OrdenFactura() { IdFactura = idFactura }, new List<Filtro>() { new Filtro(){ Tipo = TipoFiltro.Equal, Columna = NombresColumnas.IdFactura } }).FirstOrDefault();
            if (ordenFactura != null)
                dalOrdenFactura.Eliminar(ordenFactura);

            dalFactura.ConfirmarTransacción();
            dalFactura.CerrarConexión();
        }
    }
}
